use std::ops::{ Add };
use std::fmt;
use glium::uniforms::{AsUniformValue, UniformValue};

#[derive(Copy, Clone)]
pub struct Vector4(pub f32, pub f32, pub f32, pub f32);

impl Vector4 {
    pub fn zero() -> Self {
        Self(0.0, 0.0, 0.0, 0.0)
    }

    pub fn dot(self, rhs: Self) -> f32 {
        self.0 * rhs.0 + self.1 * rhs.1 + self.2 * rhs.2 + self.3 * rhs.3
    }

    pub fn as_array(&self) -> [f32; 4] {
        [self.0, self.1, self.2, self.3]
    }
}

impl AsUniformValue for Vector4 {
    fn as_uniform_value(&self) -> UniformValue {
        UniformValue::Vec4(self.as_array())
    }
}

impl fmt::Display for Vector4 {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "[{}, {}, {}, {}]", self.0, self.1, self.2, self.3)
    }
}

impl Add for Vector4 {
    type Output = Self;
    fn add(self, rhs: Self) -> Self {
        Self(self.0 + rhs.0, self.1 + rhs.1, self.2 + rhs.2, self.3 + rhs.3)
    }
}